/*
 * Copyright (c) 2009, artur
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * kiddie-os
 * 07.05.2009
 * elf.h - Elf definitions
 * 
 */

#ifndef ELF_H_
#define ELF_H_

#include <sys/types.h>

#define EI_NIDENT	16 /* Size of e_ident[] */
#define EI_MAG0		0  /* File identification */
#define EI_MAG1		1  /* File identification */
#define EI_MAG2		2  /* File identification */
#define EI_MAG3		3  /* File identification */
#define EI_CLASS	4  /* File class */
#define EI_DATA		5  /* Data encoding */
#define EI_VERSION	6  /* File version */
#define EI_PAD		7  /* Start of padding bytes */

/*
 * e_type values 
 */
#define ET_NONE		0 /* No file type */
#define ET_REL		1 /* Relocatable file */
#define ET_EXEC		2 /* Executable file */
#define ET_DYN		3 /* Shared object file */
#define ET_CORE		4 /* Core file */
#define ET_LOPROC	0xff00 /* Processor-specific */
#define ET_HIPROC	0xffff /* Processor-specific */

/*
 * ELF magic
 */
#define ELFMAG0		0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1		’E’  /* e_ident[EI_MAG1] */
#define ELFMAG2		’L’  /* e_ident[EI_MAG2] */
#define ELFMAG3		’F’  /* e_ident[EI_MAG3] */

#define ELFCLASSNONE	0  /* Invalid class */
#define ELFCLASS32		1  /* 32-bit objects */
#define ELFCLASS64		2  /* 64-bit objects */

#define ELFDATANONE		0 /* Invalid data encoding */
#define ELFDATA2LSB		1 /* byte order */
#define ELFDATA2MSB		2 /* byte order */

/*
 * e_machines values 
 */
#define EM_M32		1	/* AT&T WE 32100 */
#define EM_SPARC	2	/* SPARC */
#define EM_386		3	/* Intel Architecture */
#define EM_68K		4	/* Motorola 68000 */
#define EM_88K		5	/* Motorola 88000 */
#define EM_860		7	/* Intel 80860 */
#define EM_MIPS		8	/* MIPS RS3000 Big-Endian */
#define EM_MIPS_RS4_BE	10	/* MIPS RS4000 Big-Endian */
#define EM_ARM		40	/* ARM */

/*
 * e_value
 */
#define EV_NONE		0 /* Invalid version */
#define EV_CURRENT	1 /* Current version */

/*
 * According to ELF Spec
 *  
 * Elf32_Addr	4 4 Unsigned program address
 * Elf32_Half	2 2 Unsigned medium integer
 * Elf32_Off	4 4 Unsigned file offset
 * Elf32_Sword	4 4 Signed large integer
 * Elf32_Word	4 4 Unsigned large integer
 * unsigned char 1 1 Unsigned small integer
 * 
 */
typedef u16 Elf32_Half;
typedef u32 Elf32_Addr;
typedef u32 Elf32_Off;
typedef s32 Elf32_Sword;
typedef u32 Elf32_Word;

/*
 * Elf32 header structure
 */
typedef struct
{
	unsigned char e_ident[EI_NIDENT];
	Elf32_Half e_type;
	Elf32_Half e_machine;
	Elf32_Word e_version;
	Elf32_Addr e_entry;
	Elf32_Off e_phoff;
	Elf32_Off e_shoff;
	Elf32_Word e_flags;
	Elf32_Half e_ehsize;
	Elf32_Half e_phentsize;
	Elf32_Half e_phnum;
	Elf32_Half e_shentsize;
	Elf32_Half e_shnum;
	Elf32_Half e_shstrndx;
} Elf32_Ehdr;


#define SHN_UNDEF		0
#define SHN_LORESERVE	0xff00
#define SHN_LOPROC 		0xff00
#define SHN_HIPROC		0xff1f
#define SHN_ABS			0xfff1
#define SHN_COMMON		0xfff2
#define SHN_HIRESERVE	0xffff

#define SHT_NULL		0
#define SHT_PROGBITS 	1
#define SHT_SYMTAB		2
#define SHT_STRTAB		3
#define SHT_RELA		4
#define SHT_HASH		5
#define SHT_DYNAMIC		6
#define SHT_NOTE		7
#define SHT_NOBITS		8
#define SHT_REL			9
#define SHT_SHLIB		10
#define SHT_DYNSYM		11
#define SHT_LOPROC		0x70000000
#define SHT_HIPROC		0x7fffffff
#define SHT_LOUSER		0x80000000
#define SHT_HIUSER		0xffffffff

/*
 * Elf32 section header structure
 */
typedef struct
{
	Elf32_Word sh_name;
	Elf32_Word sh_type;
	Elf32_Word sh_flags;
	Elf32_Addr sh_addr;
	Elf32_Off sh_offset;
	Elf32_Word sh_size;
	Elf32_Word sh_link;
	Elf32_Word sh_info;
	Elf32_Word sh_addralign;
	Elf32_Word sh_entsize;
} Elf32_Shdr;

#define PF_X            0x1

#define ELF32_ST_BIND(i) ((i)>>4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))

typedef struct
{
	Elf32_Word p_type;
	Elf32_Off p_offset;
	Elf32_Addr p_vaddr;
	Elf32_Addr p_paddr;
	Elf32_Word p_filesz;
	Elf32_Word p_memsz;
	Elf32_Word p_flags;
	Elf32_Word p_align;
} Elf32_Phdr;

#endif /*ELF_H_*/
